/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.skyeye.modeling.customerized.figures;

import java.util.HashMap;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.handles.HandleBounds;

public class GPIOSocFigure extends NodeFigure implements HandleBounds {
	protected static final Dimension SIZE = new Dimension(256, 512);
	private Label label;
	protected HashMap<String, Boolean> values = new HashMap<String, Boolean>();
	protected HashMap<String, Label> connectList = new HashMap<String, Label>();

	/**
	 * @see org.eclipse.draw2d.Figure#setBounds(Rectangle)
	 */
	public void setBounds(Rectangle rect) {
		super.setBounds(rect);
	}

	/**
	 * @see org.eclipse.draw2d.Figure#setConstraint(IFigure, Object)
	 */
	public void setConstraint(IFigure child, Object constraint) {
		super.setConstraint(child, constraint);
	}

	/**
	 * Creates a new LEDFigure
	 */
	public GPIOSocFigure(HashMap<String, Boolean> values, String gpio_name) {
		this.values = values;
		for (String name : values.keySet()) {
			Label l = new Label();
			l.setText(name);
			l.setTextAlignment(Label.LEFT);
			l.setIconTextGap(5);
			this.add(l);
			connectList.put(name, l);
		}

		this.label = new Label();
		label.setText(gpio_name);
		label.setTextAlignment(Label.LEFT);
		label.setIconTextGap(5);
		this.add(label);

	}

	/**
	 * @see org.eclipse.gef.handles.HandleBounds#getHandleBounds()
	 */
	public Rectangle getHandleBounds() {
		return getBounds().getCropped(new Insets(2, 0, 2, 0));
	}

	/**
	 * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
	 */
	public Dimension getPreferredSize(int wHint, int hHint) {
		return SIZE;
	}

	/**
	 * @see org.eclipse.draw2d.Figure#paintFigure(Graphics)
	 */
	protected void paintFigure(Graphics g) {

		test(g);
	}

	final int H_MARGIN = 20;
	final int R_MARGIN = 10;
	final int LABEL_WIDTH = 60;
	final int LENGTH = 15;
	final int LINE_MARGIN = 20;

	private void test(Graphics graphics) {
		final float lineInset = Math.max(1.0f, 1) / 2.0f;
		final int inset1 = (int) Math.floor(lineInset);
		final int inset2 = (int) Math.ceil(lineInset);

		final Rectangle bound = Rectangle.SINGLETON.setBounds(getBounds());

		bound.x += inset1 + LINE_MARGIN;
		bound.y += inset1 + LINE_MARGIN;
		bound.width -= inset1 + inset2 + 2 * LINE_MARGIN;
		bound.height -= inset1 + inset2 + 2 * LINE_MARGIN;

		Point firstPoint = new Point(bound.x, bound.y);
		Point secondPoint = new Point(bound.x + bound.width, bound.y);
		Point thirdPoint = new Point(bound.x + bound.width, bound.y + bound.height);
		Point fourthPoint = new Point(bound.x, bound.y + bound.height);

		graphics.setLineWidthFloat(1);
		graphics.setForegroundColor(ColorConstants.black);

		graphics.drawLine(firstPoint, secondPoint);
		graphics.drawLine(secondPoint, thirdPoint);
		graphics.drawLine(thirdPoint, fourthPoint);
		graphics.drawLine(fourthPoint, firstPoint);

		Point pre = firstPoint;

		int connectNum = connectList.size();
		int leftNum = connectNum;
		int index = 0;
		if (connectNum * H_MARGIN > bound.height) {
			leftNum = connectNum / 2;
		}
		for (index = 0; index < leftNum; index++) {
			Point tmpS = new Point(pre.x, pre.y + H_MARGIN);
			Point tmpE = new Point(pre.x - LENGTH, pre.y + H_MARGIN);
			graphics.drawLine(tmpS, tmpE);

			Rectangle labelRect = new Rectangle(tmpS.x + R_MARGIN, tmpS.y - H_MARGIN / 2, LABEL_WIDTH, H_MARGIN);
			connectList.get("pin_" + index).setBounds(labelRect);
			// connectList.get("name_"+index).setText(""+this.values.get("name_"+index));
			FixedConnectionAnchor c;
			c = new FixedConnectionAnchor(this);
			c.offsetH = pre.x - LENGTH - bound.x + LINE_MARGIN;
			c.offsetV = pre.y - bound.y + 2 * LINE_MARGIN;
			connectionAnchors.put("pin_" + index, c);
			inputConnectionAnchors.addElement(c);
			outputConnectionAnchors.addElement(c);
			//
			// o = new FixedConnectionAnchor(this);
			// o = new FixedConnectionAnchor(this);
			// o.offsetH = pre.x-LENGTH - bound.x + 1*LINE_MARGIN+1;
			// o.offsetV = pre.y - bound.y + 2*LINE_MARGIN;
			// outputConnectionAnchors.addElement(o);
			// connectionAnchors.put("name_"+index+"_out", o);

			pre = tmpS;

		}
		pre = secondPoint;

		for (; index < connectNum; index++) {

			Point tmpS = new Point(pre.x, pre.y + H_MARGIN);
			Point tmpE = new Point(pre.x + LENGTH, pre.y + H_MARGIN);
			graphics.drawLine(tmpS, tmpE);

			Rectangle labelRect = new Rectangle(tmpS.x - R_MARGIN - LABEL_WIDTH, tmpS.y - H_MARGIN / 2, LABEL_WIDTH, H_MARGIN);
			connectList.get("pin_" + index).setBounds(labelRect);

			FixedConnectionAnchor c;
			c = new FixedConnectionAnchor(this);
			c.offsetH = secondPoint.x - firstPoint.x + LINE_MARGIN + LENGTH;
			c.offsetV = pre.y - bound.y + 2 * LINE_MARGIN;
			connectionAnchors.put("pin_" + index, c);
			inputConnectionAnchors.addElement(c);
			outputConnectionAnchors.addElement(c);
			pre = tmpS;
		}

		Rectangle tmp = new Rectangle(bound.x + 2, bound.y - 20, bound.width, 20);
		this.label.setBounds(tmp);
	}

	/**
	 * Sets the value of the LEDFigure to val.
	 * 
	 * @param val The value to set on this LEDFigure
	 */
	public void setValue(String name, boolean val) {
		this.values.put(name, val);
		repaint();
	}

	/**
	 * 
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "GPIOSocFigure";
	}

}
